<template>
	<view class="com-container" :style="{width:tableWidth,height:height+'rpx',maxHeight:maxHeight+'rpx'}">
		<view class="table-header">
			<table class="table" cellspacing="0" cellpadding="10" :bordercolor="borderColor" width="100%"
				:style="{fontSize:size+'rpx'}">
				<thead>
					<tr>
						<th class="header-td" v-for="(item,index) in column" :key="index"
							:style="{...colWidth(item),borderColor:borderColor}">
							<view :class="['cell',item.algin]">
								<template v-if="item.type==='selection'">
									<checkbox class="checkbox" :checked="allChecked" @click.stop="onSelectAll">
									</checkbox>
								</template>
								<text v-else>
									{{item.label||''}}
								</text>
							</view>
						</th>
					</tr>
				</thead>
			</table>
		</view>
		<view class="table-body">
			<table v-if="hasData" class="table" cellspacing="0" cellpadding="10" :bordercolor="borderColor" width="100%"
				:style="{fontSize:size+'rpx'}">
				<tbody>
					<tr v-for="(item,index) in  tableData" :key="index" :class="{'stripe-tr':stripe&&index%2===0}">
						<td class="body-td" v-for="(c,n) in column" :key="n"
							:style="{...colWidth(c),borderColor:borderColor}">
							<view :class="['cell',c.algin,{'single-line':showOverflow}]"
								@click="onCellClick(item,c,itemContent(item,c))">
								<template v-if="c.type==='slot'">
									<!-- #ifndef MP -->
									<slot :name="c.slotName" :row="item" :index="index"></slot>
									<!-- #endif -->
									<!-- #ifdef MP -->
									<slot name="{{c.slotName}}"></slot>
									<!-- #endif -->
								</template>
								<template v-else-if="c.type==='index'">
									<text>{{index+1}}</text>
								</template>
								<template v-if="c.type==='selection'">
									<checkbox class="checkbox" :checked="item.checked"
										@click.stop="onCellCheckChange(item)"></checkbox>
								</template>
								<text class="cell-text" v-else>
									<text>{{itemContent(item,c)}}</text>
								</text>

							</view>
						</td>
					</tr>
				</tbody>
			</table>
			<view class="noval-view" :style="{borderColor:borderColor}" v-else>
				暂无数据
			</view>
		</view>

	</view>
</template>

<script>
	export default {
		props: {
			//表格数据
			data: {
				type: Array,
				default: () => []
			},
			//列配置
			column: {
				type: Array,
				default: () => []
			},
			//宽度百分比或数字
			width: {
				type: [String, Number],
				default: '100%'
			},
			height: {
				type: [String, Number],
				default: ''
			},
			maxHeight: {
				type: [String, Number],
				default: ''
			},
			//边框颜色
			borderColor: {
				type: String,
				default: '#EBEEF5'
			},
			//是否斑马纹
			stripe: {
				type: Boolean,
				default: false
			},
			//字体大小
			size: {
				type: [String, Number],
				default: 26
			},
			//当内容过长被隐藏，单行显示
			showOverflow: {
				type: Boolean,
				default: false
			}
		},
		data() {
			return {
				tableData: []
			}
		},
		computed: {
			//表格宽度
			tableWidth() {
				if (typeof this.width === 'string') {
					return this.width.includes('%') ? this.width : `${this.width}rpx`
				}
				return `${this.width}rpx`
			},
			//单元格内容
			itemContent() {
				return (item, c) => {
					return c.formatter ? c.formatter(item, c, item[c.prop]) : item[c.prop]
				}
			},
			//是否全选
			allChecked() {
				if (this.tableData.length) {
					return this.tableData.every(item => item.checked)
				}
				return false
			},
			//列宽度
			colWidth() {
				return item => {
					let {
						width,
						type
					} = item;
					let def = {
						minWidth: '10rpx'
					}
					if (type && (type === 'selection') || type === 'index') {
						let obj = {
							width: '5rpx',
							...def
						}
						return width ? {
							...obj,
							width: `${width}rpx`
						} : obj
					}
					return width ? {
						width: `${width}rpx`,
						...def
					} : def
				}
			},
			//表格是否有数据
			hasData() {
				return Array.isArray(this.data) && this.data.length
			}
		},
		watch: {
			data: {
				handler(val) {
					if (Array.isArray(val)) {
						this.tableData = this.deepClone(val).map(item => {
							return {
								...item,
								checked: false
							}
						})

					}
				},
				immediate: true,
				deep: true
			}
		},
		methods: {
			deepClone(param) {
				function isNullOrUndefined(val) {
					return val === null || val === undefined
				}
				if (Array.isArray(param)) { //数组类型
					return param.map(item => {
						return isNullOrUndefined(item) ? item : this.deepClone(item) //null和undefined无原型直接返回
					})

				} else if (Object.prototype.toString.call(param) === '[object Object]') { //对象类型
					let obj = {}
					for (let key in param) {
						if (param.hasOwnProperty(key)) {
							obj[key] = isNullOrUndefined(param[key]) ? param[key] : this.deepClone(param[key])
						}
					}
					return obj

				}
				return param.valueOf() //其他类型（基本类型或函数）
			},
			//表格项点击
			onCellClick(row, col, cell) {
				this.$emit('cell-click', {
					row,
					col,
					cell
				})
			},
			//表格项选中
			onCellCheckChange(item) {
				item.checked = !item.checked
				this.$emit('select', {
					checked: item.checked,
					row: item
				})
				this.$emit('select-change', this.getCheckedList())
			},
			//全选
			onSelectAll() {
				let allChecked = !this.allChecked
				for (let item of this.tableData) {
					item.checked = allChecked
				}
				let checkList = this.getCheckedList()
				this.$emit('select-change', this.getCheckedList())
				this.$emit('select-all', allChecked)
			},
			//勾选项数据
			getCheckedList() {
				return this.deepClone(this.tableData.filter(item => item.checked)).map(item => {
					delete item.checked
					return item
				})
			}
		},


	}
</script>

<style lang="scss" scoped>
	.com-container {
		display: flex;
		flex-direction: column;
	}

	.table {
		text-align: center;
		table-layout: fixed;
		border-collapse: collapse;
		border: none;
	}

	.header-td {
		color: white;
		white-space: nowrap;
		overflow: hidden;
		border: 1px solid #EBEEF5;
	}

	.body-td {
		color:white;
		border: 1px solid #EBEEF5;
	}

	.cell {
		&.center {
			text-align: center;
		}

		&.left {
			text-align: left;
		}

		&.right {
			text-align: right;
		}
	}

	.stripe-tr {
		background-color: #FAFAFA;
	}

	.single-line {
		overflow: hidden;
		white-space: nowrap !important;
		text-overflow: ellipsis;

		.cell-text {
			uni-text {
				white-space: nowrap !important;
			}
		}

	}

	.checkbox {
		&::v-deep .uni-checkbox-input {
			width: 28rpx;
			height: 28rpx;

			&.uni-checkbox-input-checked {
				background-color: #007aff;
				border-color: #007aff;
				color: #fff !important;

				&::before {
					font-size: 28rpx !important;
				}
			}
		}
	}

	.table-header {
		flex-shrink: 0;
	}

	.table-body {
		margin-top: -1px;
		overflow-y: auto;
		flex: 1;
		height: 0;
	}

	.noval-view {
		font-size: 26rpx;
		color: #999;
		display: flex;
		align-items: center;
		justify-content: center;
		height: 150rpx;
		border: 1px solid #dedede;
		border-top: none;
	}
</style>